<?php

namespace IDock\Common\Tools;

use DOMDocument;

class XMLTools
{
    public static function ToXML($array, $root = 'root', $header = '', $label = '', $depth = 1): string
    {

        if (is_object($array)) {
            $array = (array)$array;
        }

        $xml = '';

        if ($header) {
            $xml .= $header;
        }
        if ($root) {
            $xml .= "<$root>";
        }

        foreach ($array as $key => $val) {
            if (is_object($val)) {
                $val = (array)$val;

                if (!is_int($key)) {
                    $xml .= "<" . $key . ">";
                }
                if ($label) {
                    $xml .= "<" . $label . ">";
                }

                $xml .= self::ToXML($val, '', '', '', $depth + 1);

                if ($label) {
                    $xml .= "</" . $label . ">";
                }

                if (!is_int($key)) {
                    $xml .= "</" . $key . ">";
                }

            } elseif (is_array($val)) {
                if (!isset($val[0])) {
                    if (is_int($key) and $label) {
                        $xml .= "<" . $label . ">" . self::ToXML($val, '', '', '', $depth + 1) . "</" . $label . ">";
                    } else {
                        $xml .= "<" . $key . ">" . self::ToXML($val, '', '', '', $depth + 1) . "</" . $key . ">";
                    }
                } else {
                    $xml .= self::ToXML($val, '', '', $key, $depth + 1);
                }
            } else {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            }
        }
        if ($root) {
            $xml .= "</$root>";
        }
        return $xml;
    }


    /**
     * @param string $xmlString
     * @param array $tagArray
     * @return array
     */
    public static function XmlToArray(string $xmlString, array $tagArray = []): array
    {
        $dom = new DOMDocument('1.0', 'UTF-8');

        $dom->loadXML($xmlString);

        return [$dom->documentElement->nodeName => self::parseXML($dom->documentElement, $tagArray)];
    }

    private static function parseXML($xmlNode, $tagArray)
    {
        if ($xmlNode->nodeType == XML_TEXT_NODE) {
            return $xmlNode->nodeValue;
        }

        if (!$xmlNode->hasChildNodes() or !$xmlNode->childNodes[0]->hasChildNodes()) {
            return $xmlNode->nodeValue;
        }
        $data = [];

        foreach ($xmlNode->childNodes as $childNode) {
            if ($childNode->nodeName == '#text') {
                continue;
            }

            if (in_array($childNode->nodeName, $tagArray)) {
                $data[$childNode->nodeName][] = self::parseXML($childNode, $tagArray);
            } else {
                $data[$childNode->nodeName] = self::parseXML($childNode, $tagArray);
            }
        }

        return $data;
    }
}
